package com.da.core.context.impl;

import com.da.core.app.BaseApp;
import com.da.core.app.impl.NIOApp;
import com.da.core.context.Request;
import com.da.core.context.Response;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

/**
 * @author da
 * @time 2023/9/17 上午 7:19
 */
public class NIOContext extends BaseContext {

    //    当前上下文的通道
    private final SocketChannel channel;
    private final BaseApp app;

    public NIOContext(SocketChannel channel, BaseApp app) {
        this.channel = channel;
        this.app = app;
        this.request = new Request(this);
        this.response = new Response(this);
        //        解析请求信息
        try {
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            StringBuilder sb = new StringBuilder();
            while (channel.read(buffer) > 0) {
                buffer.flip();
                Charset charset = StandardCharsets.UTF_8;
                CharBuffer charBuffer = charset.decode(buffer);
                sb.append(charBuffer);
                buffer.clear();
            }
            String message = sb.toString();
            BufferedReader reader = new BufferedReader(new StringReader(message));
            // 读取客户端发送的HTTP请求
            request.resolveRequest(reader);
        } catch (IOException e) {
            this.setException(e);
        }
    }

    @Override
    public InputStream getInputStream() {
        try {
            return this.channel.socket().getInputStream();
        } catch (IOException e) {
            return null;
        }
    }

    @Override
    public BaseApp getApp() {
        return this.app;
    }

    @Override
    public void flashDataToResponse() {
        String response = buildResponseMsg();
        try {
            ByteBuffer buffer = ByteBuffer.wrap(response.getBytes(StandardCharsets.UTF_8));
            while (buffer.hasRemaining()) {
                this.channel.write(buffer);
            }
//            处理data数据
            if (null != this.getData() && this.getData().length > 0) {
                this.channel.write(ByteBuffer.wrap(this.getData(), 0, this.getData().length));
            } else {
                this.channel.write(ByteBuffer.wrap("<h1 style='color:red;'>没有数据响应(这是框架的默认响应)</h1>".getBytes(StandardCharsets.UTF_8)));
            }
//            如果不是SSE请求的话,需要告诉浏览器写完了,不然传输文件时会传输不完整
            if (!this.getParams().get("Accept").equals("text/event-stream")) this.channel.shutdownOutput();
        } catch (IOException e) {
            this.setException(e);
        }
    }

    @Override
    public void close() {
        if (null != channel) {
            try {
                channel.close();
            } catch (IOException e) {
                this.setException(e);
            }
        }
    }
}
